#pragma once

#include <vector>
#include "Exception.h"
#include "definitions.h"

namespace ACCAD
{
    template<class T, bool ptr = false>
    class Stack : protected std::vector<T>
    {
    public:

        Stack()
        {
            sp = 0;
        }

        /* 
         */
        bool upToDate()
        {
            return sp == size();
        }

        void push(const T &val)
        {
            rollback();
            push_back(val);
            sp++;
        }

        const T &top()
        {
            if (sp == 0)
                throw EmptyStackException();
            return this->operator[](sp - 1);
        }

        const T &vtop()
        {
            if (upToDate())
                throw EmptyStackException();
            return this->operator[](sp);
        }

        void pop()
        {
            if (sp == 0)
                throw EmptyStackException();
            sp--;
        }

        void unpop()
        {
            if (upToDate())
                throw EmptyStackException();
            sp++;
        }

        void rollback()
        {
            while (!upToDate())
            {
                if (ptr) delete this->operator[](size() - 1);
                pop_back();
            }
        }

    private:

        uint sp;
    };
}